import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
import _classCallCheck from "@babel/runtime/helpers/esm/classCallCheck";
import _createClass from "@babel/runtime/helpers/esm/createClass";
import _inherits from "@babel/runtime/helpers/esm/inherits";
import _createSuper from "@babel/runtime/helpers/esm/createSuper";
import _applyDecoratedDescriptor from "@babel/runtime/helpers/esm/applyDecoratedDescriptor";
import _isNil from "lodash/isNil";
import _isEmpty from "lodash/isEmpty";
import _omit from "lodash/omit";
import _isArray from "lodash/isArray";

/**
 * 个性化组件
 * @date: 2019-12-15
 */
import React from 'react';
import { Row, Col } from 'antd';
import { Bind } from 'lodash-decorators';
import { queryUnitCustConfig, coverConfig, getFieldValueObject } from "./customizeTool";
import { generateFormSkeleton, generateTableColumns, generateFilterForm } from "./customizeGenerate";
export default function withCustomize(decoratorProps) {
  var _ref = decoratorProps || {},
      _ref$unitCode = _ref.unitCode,
      unitCode = _ref$unitCode === void 0 ? [] : _ref$unitCode,
      query = _ref.query,
      _ref$manualQuery = _ref.manualQuery,
      manualQuery = _ref$manualQuery === void 0 ? false : _ref$manualQuery;

  return function (Component) {
    var _dec, _dec2, _dec3, _dec4, _dec5, _dec6, _dec7, _dec8, _class;

    // eslint-disable-next-line react/no-redundant-should-component-update
    var WrapIndividual = (_dec = Bind(), _dec2 = Bind(), _dec3 = Bind(), _dec4 = Bind(), _dec5 = Bind(), _dec6 = Bind(), _dec7 = Bind(), _dec8 = Bind(), (_class = /*#__PURE__*/function (_React$PureComponent) {
      _inherits(WrapIndividual, _React$PureComponent);

      var _super = _createSuper(WrapIndividual);

      function WrapIndividual(props) {
        var _this;

        _classCallCheck(this, WrapIndividual);

        for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
          args[_key - 1] = arguments[_key];
        }

        // @ts-ignore
        _this = _super.call.apply(_super, [this, props].concat(args));
        _this.state = void 0;
        _this.state = {
          configModel: {},
          loading: true,
          cache: {}
        };
        return _this;
      }

      _createClass(WrapIndividual, [{
        key: "componentDidMount",
        value: function componentDidMount() {
          if (manualQuery) {
            return;
          }

          this.queryUnitConfig();
        }
      }, {
        key: "queryUnitConfig",
        value: function queryUnitConfig() {
          var _this2 = this;

          var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : query;

          if (unitCode && _isArray(unitCode) && unitCode.length > 0) {
            queryUnitCustConfig(_objectSpread({
              unitCode: unitCode.join(',')
            }, params)).then(function (res) {
              if (res) {
                Object.keys(res).forEach(function (code) {
                  var unitConfig = res[code];
                  var unitType = unitConfig.unitType,
                      _unitConfig$maxCol = unitConfig.maxCol,
                      maxCol = _unitConfig$maxCol === void 0 ? 3 : _unitConfig$maxCol;

                  if (unitType === 'FORM' || unitType === 'QUERYFORM') {
                    unitConfig.fields.sort(function (before, after) {
                      return (before.formRow || 0) * maxCol + before.formCol - (after.formRow || 0) * maxCol - after.formCol;
                    });
                  } else {
                    unitConfig.fields.sort(function (before, after) {
                      return (before.seq || 0) - (after.seq || 0);
                    });
                  }
                });

                _this2.setState({
                  configModel: res
                });
              }
            }).finally(function () {
              _this2.setState({
                loading: false
              });
            });
          } else {
            this.setState({
              loading: false
            });
          } // 每一次查询单元配置，便会重置window变量下的缓存对象，目前用于优化下拉框频繁调用查询接口，c7n暂时不需要


          window.CUSTOMIZECACHE = {};
        }
      }, {
        key: "customizeForm",
        value: function customizeForm() {
          var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
          var formComponent = arguments.length > 1 ? arguments[1] : undefined;
          var code = options.code,
              form = options.form,
              _options$dataSource = options.dataSource,
              dataSource = _options$dataSource === void 0 ? {} : _options$dataSource,
              _options$readOnly = options.readOnly,
              readOnly = _options$readOnly === void 0 ? false : _options$readOnly,
              dataSourceLoading = options.dataSourceLoading;
          var _this$state = this.state,
              config = _this$state.configModel,
              loading = _this$state.loading,
              cache = _this$state.cache;
          if (loading) return null;
          if (!code || _isEmpty(config[code])) return formComponent;

          if (!cache[code] && !dataSourceLoading) {
            cache[code] = {
              form: form,
              dataSource: dataSource
            };
            this.setState({
              cache: cache
            });
          }

          var _config$code$unitAlia = config[code].unitAlias,
              unitAlias = _config$code$unitAlia === void 0 ? [] : _config$code$unitAlia;
          var unitData = getFieldValueObject(unitAlias, this.getCache, code); // 获取当前单元的关联单元数据

          return customizeFormCompatible(formComponent, config[code], {
            form: form,
            code: code,
            dataSource: dataSource,
            unitData: unitData,
            readOnly: readOnly,
            getValueFromCache: this.getValueFromCache
          });
        }
      }, {
        key: "customizeTable",
        value: function customizeTable() {
          var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
          var table = arguments.length > 1 ? arguments[1] : undefined;
          var _this$state2 = this.state,
              config = _this$state2.configModel,
              loading = _this$state2.loading;
          var code = options.code,
              readOnly = options.readOnly;

          if (loading) {
            // eslint-disable-next-line no-param-reassign
            table.props.columns = []; // eslint-disable-next-line no-param-reassign

            table.props.scroll = {
              x: 0
            };
            return table;
          }

          if (!code || _isEmpty(config[code])) return table;
          var _config$code$unitAlia2 = config[code].unitAlias,
              unitAlias = _config$code$unitAlia2 === void 0 ? [] : _config$code$unitAlia2;
          var unitData = getFieldValueObject(unitAlias, this.getCache, code); // 获取当前单元的关联单元数据

          var _table$props = table.props,
              columns = _table$props.columns,
              scroll = _table$props.scroll;

          var _generateTableColumns = generateTableColumns(columns, config[code], {
            readOnly: readOnly,
            unitData: unitData,
            code: code,
            getValueFromCache: this.getValueFromCache
          }),
              newColumns = _generateTableColumns.columns,
              noWidthCount = _generateTableColumns.noWidthCount,
              scrollWidth = _generateTableColumns.scrollWidth; // eslint-disable-next-line no-param-reassign


          table.props.columns = newColumns;

          if (scroll !== undefined) {
            var originScroll = table.props.scroll; // eslint-disable-next-line no-param-reassign

            table.props.scroll = _objectSpread(_objectSpread({}, originScroll), {}, {
              x: scrollWidth + noWidthCount * 200
            });
          }

          return table;
        }
      }, {
        key: "customizeFilterForm",
        value: function customizeFilterForm() {
          var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
          var formComponent = arguments.length > 1 ? arguments[1] : undefined;
          var code = options.code,
              form = options.form,
              expand = options.expand;
          var _this$state3 = this.state,
              config = _this$state3.configModel,
              loading = _this$state3.loading;
          if (loading) return null;
          if (!code || _isEmpty(config[code])) return formComponent;
          var _config$code$unitAlia3 = config[code].unitAlias,
              unitAlias = _config$code$unitAlia3 === void 0 ? [] : _config$code$unitAlia3;
          var unitData = getFieldValueObject(unitAlias, this.getCache, code); // 获取当前单元的关联单元数据

          return filterFormCompatible(formComponent, config[code], {
            form: form,
            expand: expand,
            unitData: unitData,
            getValueFromCache: this.getValueFromCache
          });
        }
      }, {
        key: "customizeCollapse",
        value: function customizeCollapse() {
          var _this3 = this;

          var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
          var collapse = arguments.length > 1 ? arguments[1] : undefined;
          var code = options.code;
          var _this$state4 = this.state,
              config = _this$state4.configModel,
              loading = _this$state4.loading;
          if (loading) return null;
          if (!code || _isEmpty(config[code])) return collapse;
          var _config$code$fields = config[code].fields,
              fields = _config$code$fields === void 0 ? [] : _config$code$fields;
          fields.sort(function (p, n) {
            return p.seq === undefined || n.seq === undefined ? -1 : p.seq - n.seq;
          });
          var childrenMap = {};
          var newChildren = [];
          var refTabs = collapse;
          var refChildren = refTabs.props.children;

          if (_isArray(refChildren)) {
            refChildren.forEach(function (i) {
              if (i.props && i.key !== undefined) {
                childrenMap[i.key] = i;
              }
            });
          } else if (refChildren && refChildren.props && refChildren.key) {
            childrenMap[refChildren.key] = refChildren;
          }

          fields.forEach(function (i) {
            var fieldName = i.fieldName,
                fieldCode = i.fieldCode,
                conditionHeaderDTOs = i.conditionHeaderDTOs;

            var _coverConfig = coverConfig({
              visible: i.visible
            }, conditionHeaderDTOs, {
              getValueFromCache: _this3.getValueFromCache
            }),
                visible = _coverConfig.visible;

            var targetPane = childrenMap[fieldCode];

            if (fieldName !== undefined && targetPane.props) {
              var oldHeader = targetPane.props.header;

              if (typeof oldHeader === 'function') {
                targetPane.props.header = oldHeader(fieldName);
              } else {
                targetPane.props.header = /*#__PURE__*/React.createElement("h3", null, fieldName);
              }
            }

            if (visible !== 0) {
              newChildren.push(targetPane);
            }

            delete childrenMap[fieldCode];
          });
          Object.keys(childrenMap).forEach(function (i) {
            return newChildren.push(childrenMap[i]);
          });
          refTabs.props.children = newChildren;
          return collapse;
        }
      }, {
        key: "customizeTabPane",
        value: function customizeTabPane() {
          var _this4 = this;

          var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
          var tabs = arguments.length > 1 ? arguments[1] : undefined;
          var code = options.code;
          var _this$state5 = this.state,
              config = _this$state5.configModel,
              loading = _this$state5.loading;
          if (loading) return null;
          if (!code || _isEmpty(config[code])) return tabs;
          var _config$code$fields2 = config[code].fields,
              fields = _config$code$fields2 === void 0 ? [] : _config$code$fields2;
          fields.sort(function (p, n) {
            return p.seq === undefined || n.seq === undefined ? -1 : p.seq - n.seq;
          });
          var childrenMap = {};
          var newChildren = [];
          var refTabs = tabs;
          var refChildren = refTabs.props.children;

          if (_isArray(refChildren)) {
            refChildren.forEach(function (i) {
              if (i.props && i.key !== undefined) {
                childrenMap[i.key] = i;
              }
            });
          } else if (refChildren && refChildren.props && refChildren.key) {
            childrenMap[refChildren.key] = refChildren;
          }

          fields.forEach(function (i) {
            var fieldName = i.fieldName,
                fieldCode = i.fieldCode,
                conditionHeaderDTOs = i.conditionHeaderDTOs;

            var _coverConfig2 = coverConfig({
              visible: i.visible
            }, conditionHeaderDTOs, {
              getValueFromCache: _this4.getValueFromCache
            }),
                visible = _coverConfig2.visible;

            var targetPane = childrenMap[fieldCode];

            if (fieldName !== undefined && targetPane.props) {
              targetPane.props.tab = fieldName;
            }

            if (visible !== 0) {
              newChildren.push(targetPane);
            }

            delete childrenMap[fieldCode];
          });
          Object.keys(childrenMap).forEach(function (i) {
            return newChildren.push(childrenMap[i]);
          });
          refTabs.props.children = newChildren;
          return tabs;
        }
      }, {
        key: "getCache",
        value: function getCache(code) {
          return this.state.cache[code] || {};
        }
      }, {
        key: "getValueFromCache",
        value: function getValueFromCache(uCode, fieldCode) {
          var cache = this.state.cache;
          if (!cache[uCode]) return {};
          var _cache$uCode = cache[uCode],
              form = _cache$uCode.form,
              _cache$uCode$dataSour = _cache$uCode.dataSource,
              dataSource = _cache$uCode$dataSour === void 0 ? {} : _cache$uCode$dataSour;

          var allValue = _objectSpread(_objectSpread({}, dataSource), form ? form.getFieldsValue() : {});

          return allValue[fieldCode];
        }
      }, {
        key: "render",
        value: function render() {
          var newProps = _objectSpread(_objectSpread({}, this.props), {}, {
            customizeForm: this.customizeForm,
            customizeTable: this.customizeTable,
            customizeFilterForm: this.customizeFilterForm,
            customizeTabPane: this.customizeTabPane,
            customizeCollapse: this.customizeCollapse,
            queryUnitConfig: this.queryUnitConfig,
            custLoading: this.state.loading // 解决页面偶尔不刷新的问题

          });

          return /*#__PURE__*/React.createElement(Component, Object.assign({}, newProps, {
            ref: this.props.forwardRef
          }));
        }
      }]);

      return WrapIndividual;
    }(React.PureComponent), (_applyDecoratedDescriptor(_class.prototype, "queryUnitConfig", [_dec], Object.getOwnPropertyDescriptor(_class.prototype, "queryUnitConfig"), _class.prototype), _applyDecoratedDescriptor(_class.prototype, "customizeForm", [_dec2], Object.getOwnPropertyDescriptor(_class.prototype, "customizeForm"), _class.prototype), _applyDecoratedDescriptor(_class.prototype, "customizeTable", [_dec3], Object.getOwnPropertyDescriptor(_class.prototype, "customizeTable"), _class.prototype), _applyDecoratedDescriptor(_class.prototype, "customizeFilterForm", [_dec4], Object.getOwnPropertyDescriptor(_class.prototype, "customizeFilterForm"), _class.prototype), _applyDecoratedDescriptor(_class.prototype, "customizeCollapse", [_dec5], Object.getOwnPropertyDescriptor(_class.prototype, "customizeCollapse"), _class.prototype), _applyDecoratedDescriptor(_class.prototype, "customizeTabPane", [_dec6], Object.getOwnPropertyDescriptor(_class.prototype, "customizeTabPane"), _class.prototype), _applyDecoratedDescriptor(_class.prototype, "getCache", [_dec7], Object.getOwnPropertyDescriptor(_class.prototype, "getCache"), _class.prototype), _applyDecoratedDescriptor(_class.prototype, "getValueFromCache", [_dec8], Object.getOwnPropertyDescriptor(_class.prototype, "getValueFromCache"), _class.prototype)), _class));
    return React.forwardRef(function (props, ref) {
      return /*#__PURE__*/React.createElement(WrapIndividual, Object.assign({}, props, {
        forwardRef: ref
      }));
    });
  };
}

function filterFormCompatible(formComponent) {
  var config = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};

  var _ref2 = arguments.length > 2 ? arguments[2] : undefined,
      _ref2$expand = _ref2.expand,
      expand = _ref2$expand === void 0 ? false : _ref2$expand,
      form = _ref2.form,
      unitData = _ref2.unitData,
      getValueFromCache = _ref2.getValueFromCache;

  var _config$maxCol = config.maxCol,
      maxCol = _config$maxCol === void 0 ? 3 : _config$maxCol,
      fields = config.fields,
      _config$labelCol = config.labelCol,
      unitLabelCol = _config$labelCol === void 0 ? 10 : _config$labelCol,
      _config$wrapperCol = config.wrapperCol,
      unitWrapperCol = _config$wrapperCol === void 0 ? 14 : _config$wrapperCol;
  var _formComponent$props = formComponent.props;
  _formComponent$props = _formComponent$props === void 0 ? {
    children: {}
  } : _formComponent$props;
  var wrapRow = _formComponent$props.children;
  var filter = wrapRow.props ? wrapRow.props.children : [];
  if (filter.length < 2) return formComponent;

  if (!filter[0].props || !filter[1].props || !filter[0].props.children || !filter[1].props.children || !(filter[1].props.children.props || {}).children) {
    return;
  }

  var fieldRows = _isArray(filter[0].props.children) ? filter[0].props.children : [filter[0].props.children];
  var controller = filter[1].props.children;
  var formItemObj = {};
  var order = [];
  fieldRows.forEach(function (_ref3) {
    var props = _ref3.props;
    traversalFilterForm(props.children, formItemObj, order);
  });
  var newFormItem = generateFilterForm(formItemObj, fields, {
    form: form,
    unitLabelCol: unitLabelCol,
    unitWrapperCol: unitWrapperCol,
    unitData: unitData,
    getValueFromCache: getValueFromCache
  });
  fieldRows[0] = /*#__PURE__*/React.createElement(Row, null);

  if (newFormItem.length > maxCol) {
    fieldRows[1] = /*#__PURE__*/React.createElement(Row, {
      style: {
        display: expand ? 'block' : 'none'
      }
    });
  } else {
    var _fieldRows = _slicedToArray(fieldRows, 1);

    filter[0].props.children = _fieldRows[0];
    controller.props.children = (controller.props.children || []).slice(1);
  }

  newFormItem.forEach(function (i, index) {
    var target = -1;

    if (index > 2) {
      target = 1;
    } else {
      target = 0;
    }

    if (_isArray(fieldRows[target].props.children)) {
      fieldRows[target].props.children.push( /*#__PURE__*/React.createElement(Col, {
        span: Math.floor(24 / maxCol)
      }, i));
    } else {
      fieldRows[target].props.children = [/*#__PURE__*/React.createElement(Col, {
        span: Math.floor(24 / maxCol)
      }, i)];
    }
  });
  filter[0].props.children = fieldRows;
  return formComponent;
}

function customizeFormCompatible(formComponent, config, options) {
  var _formComponent$props2 = formComponent.props;
  _formComponent$props2 = _formComponent$props2 === void 0 ? {
    children: undefined
  } : _formComponent$props2;
  var rowChildren = _formComponent$props2.children,
      _formComponent$props3 = _formComponent$props2.className,
      className = _formComponent$props3 === void 0 ? '' : _formComponent$props3;
  var formItemObj = {}; // eslint-disable-next-line no-param-reassign

  options.className = className;

  if (_isArray(rowChildren)) {
    rowChildren.forEach(function (row, index) {
      if (!_isNil(row) && typeof row === 'object') {
        traversalStandardForm(row.props.children, formItemObj, index, 0, _omit(row.props, ['children']));
      }
    });
  } else {
    traversalStandardForm((rowChildren.props || {}).children, formItemObj, 0, 0, _omit(rowChildren.props, ['children']));
  }

  return generateFormSkeleton(formItemObj, config, options);
}

function traversalStandardForm(reactElement) {
  var formObj = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  var row = arguments.length > 2 ? arguments[2] : undefined;
  var col = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 0;
  var rowProps = arguments.length > 4 ? arguments[4] : undefined;
  if (!reactElement) return;

  if (_isArray(reactElement)) {
    reactElement.forEach(function (i, _index) {
      return traversalStandardForm(i, formObj, row, _index, rowProps);
    });
  } else if (reactElement.props.span) {
    var singleFormItem = reactElement.props.children;

    if (singleFormItem.type && singleFormItem.type.defaultProps && singleFormItem.type.defaultProps.prefixCls === 'ant-form') {
      var fieldCode;
      var formChildren = singleFormItem.props.children;

      if (_isArray(formChildren)) {
        for (var i = 0; i < formChildren.length; i++) {
          if (formChildren[i].props && formChildren[i].props['data-__field'] !== undefined) {
            fieldCode = formChildren[i].props['data-__field'].name;
            break;
          }
        }
      } else if (formChildren.props && formChildren.props['data-__field']) {
        fieldCode = formChildren.props['data-__field'].name;
      } // eslint-disable-next-line no-param-reassign


      formObj[fieldCode] = {
        formItem: singleFormItem,
        row: row + 1,
        col: col + 1,
        rowProps: rowProps,
        colProps: reactElement.props
      };
    }
  }
}

function traversalFilterForm(reactElement) {
  var formObj = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
  var order = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [];
  if (!reactElement) return;

  if (_isArray(reactElement)) {
    reactElement.forEach(function (i) {
      return traversalFilterForm(i, formObj, order);
    });
  } else if (reactElement.props.span) {
    var singleFormItem = reactElement.props.children;

    if (singleFormItem.type && singleFormItem.type.defaultProps && singleFormItem.type.defaultProps.prefixCls === 'ant-form') {
      var fieldCode;
      var formChildren = singleFormItem.props.children;

      if (_isArray(formChildren)) {
        for (var i = 0; i < formChildren.length; i++) {
          if (formChildren[i].props && formChildren[i].props['data-__field'] !== undefined) {
            fieldCode = formChildren[i].props['data-__field'].name;
            break;
          }
        }
      } else if (formChildren.props && formChildren.props['data-__field']) {
        fieldCode = formChildren.props['data-__field'].name;
      } // eslint-disable-next-line no-param-reassign


      formObj[fieldCode] = singleFormItem;
      order.push(fieldCode);
    }
  }
}